<?PHP
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/
	
	/**
	 * A class used to send a simple E-Mail.  After constructing the E-Mail object
	 * call lib_email::send() when ready to send out the message.
	 */
	class lib_email {
		const E_NONE = 0;
		const E_CON_FAILED = 1;
		const E_BAD_RESPONSE = 2;
		const E_INVALID_LOGIN = 3;
		const E_INVALID_FROM = 4;
		const E_INVALID_TO = 5;
		const E_SENDING_FAILED = 6;
		
		private $smtp_user;
		private $smtp_pass;
		private $smtp_host;
		private $smtp_port;
		
		private $to;
		private $subject;
		private $message;
		private $from;
		
		private $con;
		
		/**
		 * Prepare an E-Mail to be sent out
		 *
		 * @param string $to The E-Mail address to send the message to
		 * @param string $subject The subject of the E-Mail
		 * @param string $message The message to be sent in the E-Mail
		 * @param string $from The address of the sender of the message
		 */
		public function __construct($to,$subject,$message){
			$this->to = $to;
			$this->subject = $subject;
			$this->message = $message;
			
			// This next block of code is specific to X7 Chat 3
			global $settings;
			$this->from = $settings['admin_email'];
			if($settings['use_smtp']){
				$this->smtp_user = $settings['smtp_user'];
				$this->smtp_pass = $settings['smtp_pass'];
				$this->smtp_host = $settings['smtp_host'];
				$this->smtp_port = $settings['smtp_port'];
			}
			
		}
		
		/**
		 * Send out the message
		 *
		 * @return lib_email::E_NONE if the message might have been sent successfully, 
		 * the error code if the message could not be sent.
		 */
		function send(){
			// Strip \r\n from subject
			$this->subject = preg_replace("#[\r\n]#",'',$this->subject);
			
			// Convert bare \n's in message to \r\n, non standards compliant SMTP servers are out of luck
			$this->message = preg_replace("#(?<!\r)\n#","\r\n",$this->message);
			
			// See if the message they gave us is HTML or plaintext
			if(strpos($this->message,'<') !== false){
				// HTML
				$message_html = $this->message;
				$message_plain = strip_tags(str_replace("<br />","\r\n",$this->message));
			}else{
				// plaintext
				$message_html = nl2br($this->message);
				$message_plain = $this->message;
			}
			
			// Generate some boundries
			$boundry1 = md5(time());
			
			// Generate the message
			$message  = 
				  "--$boundry1\r\n"
			 	. "Content-Transfer-Encoding: 8bit\r\n"
			 	. "Content-Type: text/plain; charset=\"UTF-8\"\r\n\r\n"
				. "{$message_plain}\r\n\r\n"
				. "--$boundry1\r\n"
				. "Content-Transfer-Encoding: 8bit\r\n"
				. "Content-Type: text/html; charset=\"UTF-8\"\r\n\r\n"
				. "{$message_html}\r\n\r\n"
				. "--$boundry1--\r\n";
			
			$headers = 
				  "Date: ".date('r')."\r\n"
				. "X-Mailer: X7C3/PHP/".phpversion()."\r\n"
				. "Message-ID: <".time().".X7C3@{$_SERVER['SERVER_NAME']}>\r\n"
				. "Reply-To: {$this->from}\r\n"
				. "Return-Path: {$this->from}\r\n"
				. "Mime-Version: 1.0\r\n"
				. "From: {$this->from}\r\n"
				. "Content-Transfer-Encoding: 8bit\r\n"
				. "Content-Type: multipart/alternative; boundary=\"$boundry1\"\r\n"
				. "Subject: {$this->subject}\r\n"
				. "To: {$this->to}\r\n";
				
			// How to send this message?
			if($this->smtp_host !== null){
				// Use SMTP server
				
				if(!($this->con = fsockopen($this->smtp_host,$this->smtp_port,$errno,$errstr,15)))
					return lib_email::E_CON_FAILED;
					
				if(!$this->get_response(220))
					return lib_email::E_BAD_RESPONSE;
					
				// See if authentication is needed
				if(!empty($this->smtp_user)){
					// It is, good the server admin is not stupid
					fputs($this->con,"EHLO {$this->smtp_host}\r\n");
					if(!$this->get_response(250))
						return lib_email::E_BAD_RESPONSE;
					fputs($this->con,"AUTH LOGIN\r\n");
					if(!$this->get_response(334))
						return lib_email::E_BAD_RESPONSE;
					fputs($this->con,base64_encode($this->smtp_user)."\r\n");
					if(!$this->get_response(334))
						return lib_email::E_INVALID_LOGIN;
					fputs($this->con,base64_encode($this->smtp_pass)."\r\n");
					if(!$this->get_response(235))
						return lib_email::E_INVALID_LOGIN;
				
				}else{
					fputs($this->con,"HELO {$this->smtp_host}\r\n");
					if(!$this->get_response(250))
						return lib_email::E_BAD_RESPONSE;
				}
				
				// Connection established if you made it this far
				fputs($this->con,"MAIL FROM: <{$this->smtp_user}>\r\n");
				if(!$this->get_response(250))
					return lib_email::E_INVALID_FROM;
				fputs($this->con,"RCPT TO: <{$this->to}>\r\n");
				if(!$this->get_response(250))
					return lib_email::E_INVALID_TO;
				
				fputs($this->con,"DATA\r\n");
				if(!$this->get_response(354))
					return lib_email::E_BAD_RESPONSE;
				
				// Send everything
				fputs($this->con,"{$headers}\r\n{$message}\r\n\r\n.\r\n");
				if(!$this->get_response(250))
					return lib_email::E_BAD_RESPONSE;
					
				// Goodbye
				fputs($this->con,"QUIT\r\n");
				fclose($this->con);
					
			}else{
				// Fine make it easy
				if(!mail($this->to,$this->subject,$this->message,$headers))
					return lib_email::E_SENDING_FAILED;
			}
			
			return lib_email::E_NONE;
		}
		
		/**
		 * Get a response from the SMTP server
		 *
		 * @param int $check_code The return code to check for
		 * @return True if the return codes matched, false if they did not
		 */
		private function get_response($check_code){
			$response = fgets($this->con,256);
			$inInfo = stream_get_meta_data($this->con);
			while($inInfo['unread_bytes'] > 0){
				$response .= fgets($this->con,256);
				$inInfo = stream_get_meta_data($this->con);
			}
			
			return (substr($response,0,3) == $check_code);
		}
		
	}
?>